home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_87 / vtplay.pas < prev    next >
Pascal/Delphi Source File  |  1995-01-01  |  21KB  |  811 lines

  1. UNIT VTPlay;
  2.  
  3. INTERFACE
  4.  
  5. USES VTGlobal, VTWins, VTStrConst, StrConst,
  6.      SongUnit, SongElements, PlayMod,
  7.      Output43, vid43,
  8.      Filters, Debugging;
  9.  
  10.  
  11.  
  12.  
  13. {----------------------------------------------------------------------------}
  14. { Definiciones generales                                                     }
  15. {____________________________________________________________________________}
  16.  
  17. PROCEDURE InitPlayData(VAR Song: TSong);
  18.  
  19.  
  20.  
  21.  
  22. {----------------------------------------------------------------------------}
  23. { Definiciones para la ventana de información de posición.                   }
  24. {____________________________________________________________________________}
  25.  
  26. VAR
  27.   LastFilterOn,
  28.   LastFilterOff : TFilterMethod;
  29.   LastFilter    : BOOLEAN;
  30.  
  31. PROCEDURE UpdateRunInfo(spd, patt, pos, seq, PSize: WORD);
  32.  
  33.  
  34.  
  35.  
  36. {----------------------------------------------------------------------------}
  37. { Definiciones para las barras de vúmetros.                                  }
  38. {____________________________________________________________________________}
  39.  
  40. VAR
  41.   barlen         : ARRAY[1..MaxChannels] OF BYTE;
  42.   barofs         : ARRAY[1..4]           OF WORD;
  43.  
  44. PROCEDURE UpdateBars;
  45.  
  46. PROCEDURE ParseBarInit(VAR nt: TFullNote; i: WORD);
  47.  
  48.  
  49.  
  50.  
  51. {----------------------------------------------------------------------------}
  52. { Definiciones para las ventanas de información de notas.                    }
  53. {____________________________________________________________________________}
  54.  
  55. VAR
  56.   SampleStrings : ARRAY[1..99] OF STRING[24];
  57.   VolumeStrings : ARRAY[0..64] OF STRING[2];
  58.  
  59.   DispVolumes   : ARRAY[1..MaxChannels] OF BYTE;
  60.   DispNotes     : ARRAY[1..MaxChannels] OF TFullNote;
  61.   RealVolumes   : ARRAY[1..MaxChannels] OF BYTE;
  62.   RealNotes     : ARRAY[1..MaxChannels] OF TFullNote;
  63.  
  64.   DispSplName   : ARRAY[1..MaxChannels] OF BYTE;
  65.  
  66. PROCEDURE UpdateNoteInfo(VAR Song: TSong; VAR nt: TFullNote; i: WORD);
  67.  
  68. PROCEDURE Update2ndLine(NewNote: BOOLEAN);
  69.  
  70.  
  71.  
  72.  
  73. {----------------------------------------------------------------------------}
  74. { Definiciones para las ventanas de información de samples.                  }
  75. {____________________________________________________________________________}
  76.  
  77. VAR
  78.   DispSamples   : ARRAY[1..31] OF BYTE;
  79.   RealSamples   : ARRAY[1..31] OF BYTE;
  80.  
  81.   siPermiso     : BOOLEAN;                  { Sample information }
  82.   siTickForce   : BOOLEAN;
  83.   siCounter     : BYTE;
  84.  
  85. CONST
  86.   sfNoSample = 0;
  87.   sfNotUsed  = 1;
  88.   sfUsed     = 2;
  89.   sfNowUsed  = 3;
  90.   sfFlashing = 4;
  91.  
  92. PROCEDURE UpdateSampleInfo(VAR Song: TSong; VAR nt: TFullNote; i: WORD);
  93.  
  94. PROCEDURE TickSampleInfo;
  95.  
  96. PROCEDURE SampleAttr(s, a: BYTE);
  97.  
  98.  
  99.  
  100.  
  101. {----------------------------------------------------------------------------}
  102. { Definiciones para la ventana de osciloscopio.                              }
  103. {____________________________________________________________________________}
  104.  
  105. VAR
  106.   OscWinBuff    : ARRAY[1..16, 1..51*2] OF CHAR;
  107.   OscSamples    : ARRAY[1..700] OF INTEGER;
  108.  
  109. PROCEDURE UpdateOscilloscInfo;
  110.  
  111.  
  112.  
  113.  
  114. {----------------------------------------------------------------------------}
  115. { Definiciones para la ventana de canal on/off.                              }
  116. {____________________________________________________________________________}
  117.  
  118. VAR
  119.   DispPermisos   : ARRAY[1..4] OF BOOLEAN;
  120.  
  121. PROCEDURE UpdateOnOff;
  122.  
  123.  
  124.  
  125.  
  126. IMPLEMENTATION
  127.  
  128. USES SongUtils;
  129.  
  130.  
  131.  
  132.  
  133. {----------------------------------------------------------------------------}
  134. { Implementación de la ventana de información de posición.                   }
  135. {____________________________________________________________________________}
  136.  
  137. PROCEDURE UpdateRunInfo(spd, patt, pos, seq, PSize: WORD);
  138.   CONST
  139.     s    : STRING   = '';
  140.     aon  : BYTE     = 0;
  141.     aoff : BYTE     = 0;
  142.   BEGIN
  143.  
  144.     WITH wRunInfo DO 
  145.       IF wTopLine.vis AND wTopLine.act THEN BEGIN
  146.         IF pos > 99 THEN pos := 1;
  147.         STR(seq   : 3, s); DirectWrite (ParseCoords(x+wriX1,   y+1), s);
  148.         STR(patt  : 3, s); DirectWrite (ParseCoords(x+wriX1,   y+2), s);
  149.         STR(pos   : 3, s); DirectWrite (ParseCoords(x+wriX1,   y+3), s);
  150.         STR(PSize : 3, s); DirectWrite (ParseCoords(x+wriX2,   y+3), s);
  151.         STR(spd   : 3, s); DirectWrite (ParseCoords(x+wriX1,   y+4), s);
  152.  
  153.         IF (LastFilter    <> FilterIsOn) OR
  154.            (LastFilterOn  <> FilterOn)   OR
  155.            (LastFilterOff <> FilterOff)  OR wTopLine.forz THEN BEGIN
  156.           IF FilterIsOn THEN BEGIN
  157.             aon  := BYTE(col[4]);
  158.             aoff := BYTE(col[2]);
  159.           END ELSE BEGIN
  160.             aon  := BYTE(col[2]);
  161.             aoff := BYTE(col[4]);
  162.           END;
  163.           s[0] := #1;
  164.           s[1] := CHAR(ORD(FilterOn)  + ORD('0'));
  165.           DirectWriteAttr(ParseCoords(x+wriX2+1, y+4), s, aon);
  166.           s[1] := CHAR(ORD(FilterOff) + ORD('0'));
  167.           DirectWriteAttr(ParseCoords(x+wriX2+2, y+4), s, aoff);
  168.           LastFilter    := FilterIsOn;
  169.           LastFilterOn  := FilterOn;
  170.           LastFilterOff := FilterOff;
  171.         END;
  172.  
  173.       END;
  174.  
  175.   END;
  176.  
  177.  
  178.  
  179.  
  180. {----------------------------------------------------------------------------}
  181. { Implementación de las barras de vúmetros.                                  }
  182. {____________________________________________________________________________}
  183.  
  184. PROCEDURE MyWriteBar; ASSEMBLER;
  185.   ASM
  186.         MOV     BH,w2ndLine.act
  187.         AND     BH,w2ndLine.vis
  188.         AND     BH,BH
  189.         JZ      @@fin
  190.  
  191.         MOV     BL,BYTE PTR [wPlayBars.col+1]
  192.         MOV     AX,WORD PTR [wPlayBars.col+2]
  193.         MOV     CL,BarVal
  194.  
  195.         MOV     DH,13
  196.         MOV     CH,16
  197.         AND     DL,DL
  198.         JZ      @@floop
  199. @@gloop: MOV    BYTE PTR [ES:SI+1],AL
  200.          MOV    BYTE PTR [ES:SI],CL
  201.          DEC    DL
  202.          JNZ    @@nofr1
  203.  
  204.          INC    BYTE PTR [ES:SI]
  205.          INC    SI
  206.          INC    SI
  207.          DEC    CH
  208.          JMP    @@floop
  209.  
  210. @@nofr1: INC    SI
  211.          INC    SI
  212.          DEC    CH
  213.          DEC    DL
  214.          JZ     @@floop
  215.          DEC    DH
  216.          JNZ     @@gloop
  217.  
  218. @@rloop: MOV    BYTE PTR [ES:SI+1],AH
  219.          MOV    BYTE PTR [ES:SI],CL
  220.          DEC    DL
  221.          JNZ    @@nofr2
  222.  
  223.          INC    BYTE PTR [ES:SI]
  224.          INC    SI
  225.          INC    SI
  226.          DEC    CH
  227.          JZ     @@fin
  228.          JMP    @@floop
  229.  
  230. @@nofr2: INC    SI
  231.          INC    SI
  232.          DEC    CH
  233.          JZ     @@fin
  234.          DEC    DL
  235.          JNZ     @@rloop
  236.  
  237. @@floop: MOV    BYTE PTR [ES:SI],CL
  238.          INC    SI
  239.          MOV    BYTE PTR [ES:SI],BL
  240.          INC    SI
  241.          DEC    CH
  242.          JNZ     @@floop
  243. @@fin:
  244.   END;
  245.  
  246.  
  247.  
  248.  
  249. PROCEDURE WriteBar(i: WORD); ASSEMBLER;
  250.   ASM
  251.         MOV     AX,i
  252.         DEC     AX
  253.         MOV     BX,OFFSET barlen
  254.         ADD     BX,AX
  255.         MOV     DL,[BX]
  256.         INC     AL
  257.         SUB     AL,[FirstChannel]
  258.         JC      @@Fin
  259.         CMP     AL,4
  260.         JAE     @@Fin
  261.         MOV     SI,ScrSegment
  262.         CMP     SI,$A000
  263.         JC      @@Fin
  264.         MOV     ES,SI
  265.         MOV     SI,OFFSET barofs
  266.         ADD     SI,AX
  267.         ADD     SI,AX
  268.         MOV     SI,[SI]
  269.         CALL    MyWriteBar
  270. @@Fin:
  271.   END;
  272.  
  273.  
  274.  
  275.  
  276. PROCEDURE InitBar(i, l: WORD);
  277.   BEGIN
  278.     IF l > 32 THEN l := 32;
  279.     barlen[i] := l+1;
  280.     IF Permisos[i] THEN WriteBar(i);
  281.   END;
  282.  
  283.  
  284.  
  285. PROCEDURE UpdateBars;
  286.   CONST
  287.     i : WORD = 0;
  288.   BEGIN
  289.     FOR i := 1 TO MaxChannels DO
  290.       BEGIN
  291.       IF barlen[i] > 0 THEN
  292.         BEGIN
  293.           DEC(barlen[i]);
  294.           IF Permisos[i] AND wPlayBars.act AND wPlayBars.vis THEN
  295.             WriteBar(i);
  296.         END
  297.       ELSE
  298.         IF wPlayBars.act AND wPlayBars.vis THEN
  299.           WriteBar(i);
  300.       END;
  301.   END;
  302.  
  303. (*
  304. PROCEDURE UpdateBars; ASSEMBLER;
  305.   ASM
  306.         MOV     ES,ScrSegment
  307.  
  308.         MOV     CX,4
  309.         MOV     BX,OFFSET Permisos
  310.         MOV     SI,OFFSET barlen
  311.         MOV     DI,OFFSET barofs
  312. @@loop:  XOR    DL,DL
  313.          MOV    AL,[BX]
  314.          AND    AL,AL
  315.          JZ     @@DoWrite
  316.          MOV    DL,[SI]
  317.          AND    DL,DL
  318.          JNZ    @@dodec
  319.  
  320.          MOV    AL,[wPlayBars.forz]
  321.          OR     AL,[w2ndLine.forz]
  322.          OR     AL,AL
  323.          JNZ    @@DoWrite
  324.          JMP    @@next
  325.  
  326. @@dodec:  DEC   BYTE PTR [SI]
  327.           DEC   DL
  328. @@DoWrite:PUSH  BX
  329.           PUSH  CX
  330.           PUSH  SI
  331.           MOV   SI,[DI]
  332.           CALL  MyWriteBar
  333.           POP   SI
  334.           POP   CX
  335.           POP   BX
  336. @@next:  INC    SI
  337.          INC    DI
  338.          INC    DI
  339.          INC    BX
  340.          DEC    CL
  341.          JNZ    @@loop
  342.   END;
  343. *)
  344.  
  345.  
  346.  
  347. PROCEDURE ParseBarInit(VAR nt: TFullNote; i: WORD);
  348.   BEGIN
  349.  
  350.     IF      nt.Command     = mcSetVolume THEN InitBar(i, nt.Parameter      SHR 1)
  351.     ELSE IF nt.Instrument <> 0           THEN InitBar(i, Canales[i].Volume SHR 1)
  352.     ELSE IF nt.Period     <> 0           THEN InitBar(i, RealVolumes[i]    SHR 1);
  353.  
  354.   END;
  355.  
  356.  
  357.  
  358.  
  359. {----------------------------------------------------------------------------}
  360. { Implementación de las ventanas de información de notas.                    }
  361. {____________________________________________________________________________}
  362.  
  363. PROCEDURE UpdateNoteInfo(VAR Song: TSong; VAR nt: TFullNote; i: WORD);
  364.   CONST
  365.     s        : STRING         = '';
  366.     MySample : BYTE           = 0;
  367.     vol      : WORD           = 0;
  368.     f        : BOOLEAN        = FALSE;
  369.     p        : PFullNote      = NIL;
  370.     Instr    : PInstrumentRec = NIL;
  371.   BEGIN
  372.     IF w2ndLine.forz AND w2ndLine.vis AND w2ndLine.act AND
  373.        (i >= FirstChannel) AND (i < FirstChannel+4)    THEN
  374.       BEGIN
  375.         STR(i : 2, s);
  376.         WITH wChannelNum DO
  377.           DirectWrite(ParseCoords(x+1, y+i-FirstChannel+1), s);
  378.  
  379.         IF NOT PlayMod.Permisos[i] THEN
  380.           BEGIN
  381.             WITH wInfoNote  DO DirectWrite(ParseCoords(x+1, y+i-FirstChannel+1), '                            ');
  382.             WITH wRunSample DO DirectWrite(ParseCoords(x+1, y+i-FirstChannel+1), '                        ');
  383.           END;
  384.       END;
  385.  
  386.     p := @DispNotes[i];
  387.  
  388.     WITH RealNotes[i] DO BEGIN
  389.  
  390.       IF (nt.Period <> Period) AND (nt.Period <> 0) THEN
  391.         Period := nt.Period
  392.       ELSE
  393.         Period := p^.Period;
  394.  
  395.       IF (nt.Instrument <> Instrument) AND (nt.Instrument <> 0) THEN
  396.         Instrument := nt.Instrument
  397.       ELSE
  398.         Instrument := p^.Instrument;
  399.  
  400.       vol := $FFFF;
  401.  
  402.       IF (nt.Period <> 0) OR (nt.Instrument <> 0) THEN vol := Canales[i].Volume;
  403.       IF nt.Command = mcSetVolume THEN vol := nt.Parameter;
  404.  
  405.       IF (vol <> $FFFF) AND (vol <> RealVolumes[i]) THEN
  406.         RealVolumes[i] := vol
  407.       ELSE
  408.         vol := RealVolumes[i];
  409.  
  410.       IF w2ndLine.act AND w2ndLine.vis AND PlayMod.Permisos[i] THEN BEGIN
  411.         IF w2ndLine.forz OR (p^.Period <> Period) THEN BEGIN
  412.           IF Period <> 0 THEN
  413.             BEGIN
  414.               p^.Period := Period;
  415.  
  416.               IF (i >= FirstChannel) AND (i < FirstChannel+4) THEN
  417.                 BEGIN
  418.                   NoteFreq(Period, s);
  419.                   WITH wInfoNote DO DirectWrite(ParseCoords(x+winX1, y+i-FirstChannel+1), s);
  420.                 END;
  421.             END;
  422.         END;
  423.  
  424.         IF w2ndLine.forz OR (Instrument <> p^.Instrument) THEN BEGIN
  425.           p^.Instrument := Instrument;
  426.           IF (i >= FirstChannel) AND (i < FirstChannel+4) THEN
  427.             WITH wInfoNote DO
  428.               BEGIN
  429.                 Instr := PInstrument(Song.GetInstrument(p^.Instrument))^.Instr;
  430.                 IF Instr <> NIL THEN
  431.                   BEGIN
  432.                     STR(Instr^.reps : 6, s); DirectWrite(ParseCoords(x+winX3, y+i-FirstChannel+1), s);
  433.                     STR(Instr^.repl : 6, s); DirectWrite(ParseCoords(x+winX4, y+i-FirstChannel+1), s);
  434.                     STR(Instr^.len  : 6, s); DirectWrite(ParseCoords(x+winX5, y+i-FirstChannel+1), s);
  435.                   END
  436.                 ELSE
  437.                   BEGIN
  438.                     DirectWrite(ParseCoords(x+winX3, y+i-FirstChannel+1), '      ');
  439.                     DirectWrite(ParseCoords(x+winX4, y+i-FirstChannel+1), '      ');
  440.                     DirectWrite(ParseCoords(x+winX5, y+i-FirstChannel+1), '     ');
  441.                   END;
  442.               END;
  443.         END;
  444.  
  445.         IF w2ndLine.forz OR (Instrument <> DispSplName[i]) THEN BEGIN
  446.           DispSplName[i]   := Instrument;
  447.           IF (i >= FirstChannel) AND (i < FirstChannel+4) THEN
  448.             WITH wRunSample DO
  449.               IF Instrument <> 0 THEN
  450.                 DirectWrite(ParseCoords(x+1, y+i-FirstChannel+1), SampleStrings[Instrument])
  451.               ELSE
  452.                 DirectWrite(ParseCoords(x+1, y+i-FirstChannel+1), '                        ');
  453.         END;
  454.  
  455.         IF w2ndLine.forz OR (DispVolumes[i] <> vol) THEN BEGIN
  456.           DispVolumes[i]   := vol;
  457.           IF (i >= FirstChannel) AND (i < FirstChannel+4) THEN
  458.             WITH wInfoNote DO
  459.               IF DispVolumes[i] <> $FF THEN
  460.                 DirectWrite(ParseCoords(x+winX2, y+i-FirstChannel+1), VolumeStrings[vol])
  461.               ELSE
  462.                 DirectWrite(ParseCoords(x+winX2, y+i-FirstChannel+1), '  ');
  463.         END;
  464.  
  465.       END;
  466.     END;
  467.   END;
  468.  
  469.  
  470.  
  471.  
  472. PROCEDURE SampleAttr(s, a: BYTE);
  473.   BEGIN
  474.     IF s > 15 THEN
  475.       WITH wSamples2 DO RectAttr(ParseCoords(x+wsX1, y+s-15), 22, 1, a)
  476.     ELSE
  477.       WITH wSamples1 DO RectAttr(ParseCoords(x+wsX1, y+s),    22, 1, a);
  478.   END;
  479.  
  480.  
  481.  
  482.  
  483. PROCEDURE UpdateSampleInfo(VAR Song: TSong; VAR nt: TFullNote; i: WORD);
  484.   CONST
  485.     j      : WORD = 0;
  486.   LABEL
  487.     Passa;
  488.   BEGIN                 
  489.     IF i = 1 THEN BEGIN
  490.       FOR j := 1 TO 31 DO
  491.         IF RealSamples[j] >= sfNowUsed THEN
  492.           RealSamples[j] := sfUsed;
  493.     END;
  494.  
  495.     IF Permisos[i] AND (RealNotes[i].Instrument <> 0) THEN
  496.       IF (nt.Instrument <> 0) OR (nt.Period <> 0) OR ((nt.Command = mcSetVolume) AND (nt.Parameter <> 0)) THEN
  497.         RealSamples[RealNotes[i].Instrument] := sfFlashing
  498.       ELSE
  499.         IF RealSamples[RealNotes[i].Instrument] <> sfFlashing THEN
  500.           RealSamples[RealNotes[i].Instrument] := sfNowUsed;
  501.  
  502.     IF i = Song.NumChannels THEN BEGIN
  503. {
  504.       siCounter := NoteSound^.Tempo-1;
  505.       IF siCounter < 2 THEN siCounter := 2;
  506. }
  507. siCounter := 0;
  508.  
  509.       WITH wSamples DO BEGIN
  510.         siPermiso := act AND vis;
  511.  
  512.         IF siPermiso AND forz THEN BEGIN
  513. {          InitSampleWin(Song);}
  514.           siTickForce := forz;
  515. {          TickSampleInfo;}
  516.         END;
  517.  
  518.         forz := FALSE;
  519.       END;
  520.     END;
  521.   END;
  522.  
  523.  
  524.  
  525.  
  526. PROCEDURE TickSampleInfo;
  527.   CONST
  528.     i  : WORD = 0;
  529.     vl : BYTE = 0;
  530.   BEGIN
  531.     WITH wSamples DO 
  532.       IF NOT (act AND vis) THEN EXIT;
  533.  
  534.     INC(siCounter);
  535.  
  536.     FOR i := 1 TO 31 DO BEGIN
  537.       vl := RealSamples[i];
  538.       IF (siCounter > NoteSound^.Tempo) AND (vl = sfFlashing) THEN
  539.         BEGIN
  540.           vl             := sfNowUsed;
  541.           RealSamples[i] := sfNowUsed;
  542.         END;
  543.  
  544.       IF (vl > sfNoSample) AND ((vl <> DispSamples[i]) OR siTickForce) THEN
  545.         BEGIN
  546.           DispSamples[i] := vl;
  547.  
  548.           IF siPermiso THEN
  549.             SampleAttr(i, BYTE(wSamples1.col[vl+4]));
  550.         END;
  551.     END;
  552.  
  553.     siTickForce := FALSE;
  554.  
  555.   END;
  556.  
  557.  
  558.  
  559.  
  560. PROCEDURE UpdateOnOff;
  561.   CONST
  562.     Strn : ARRAY[0..1] OF STRING[3] = ('OFF', 'ON ');
  563.     i    : WORD = 0;
  564.   BEGIN
  565.     IF w2ndLine.act AND w2ndLine.vis THEN
  566.       FOR i := 1 TO 4 DO
  567.         IF w2ndLine.forz OR (Permisos[FirstChannel - 1 + i] <> DispPermisos[i]) THEN BEGIN
  568.           DispPermisos[i] := Permisos[FirstChannel - 1 + i];
  569.           WITH wVoiceOnOff DO DirectWrite(ParseCoords(x+1, y+i), Strn[ORD(Permisos[FirstChannel - 1 + i])]);
  570.         END;
  571.   END;
  572.  
  573.  
  574.  
  575.  
  576. PROCEDURE Update2ndLine(NewNote: BOOLEAN);
  577.   BEGIN
  578.  
  579.      UpdateOnOff;
  580.      UpdateBars;
  581.  
  582.      IF NewNote THEN
  583.        w2ndLine.forz := FALSE;
  584.  
  585.   END;
  586.  
  587.  
  588.  
  589.  
  590. PROCEDURE PutStr(VAR Buf; VAR s: STRING; c: BYTE);
  591.   CONST
  592.     i : WORD = 0;
  593.   VAR
  594.     CBuf : ARRAY[1..32000, 1..2] OF BYTE ABSOLUTE Buf;
  595.   BEGIN
  596.  
  597.     FOR i := 1 TO Length(s) DO BEGIN
  598.       CBuf[i][1] := BYTE(s[i]);
  599.       CBuf[i][2] := c;
  600.     END;
  601.  
  602.   END;
  603.  
  604.  
  605. (*
  606. PROCEDURE InitOscilloscInfo;
  607.   CONST
  608.     EmptyStr : STRING[51] = '                                                   ';
  609.     OscView  : STRING[30] = '';
  610.     i        : WORD       = 0;
  611.     j        : WORD       = 0;
  612.     ofs      : WORD       = 0;
  613.   VAR
  614.     OscWinBuff    : ARRAY[1..16, 1..51*2] OF CHAR;
  615.   BEGIN
  616.     OscView := GetString(StrOscilloscView);
  617.     WITH wOscillosc DO BEGIN
  618.       FOR i := 1 TO 16 DO PutStr(OscWinBuff[i], EmptyStr, BYTE(col[1]));
  619.       PutStr(OscWinBuff[1][21*2-1], OscView, BYTE(col[1]));
  620.       FOR i := 3 TO 14 DO BEGIN
  621.         OscWinBuff[i][4] := col[1];
  622.         OscWinBuff[i][6] := col[1];
  623.         OscWinBuff[i][8] := col[1];
  624.         OscWinBuff[i][3] := ' ';
  625.         OscWinBuff[i][5] := ' ';
  626.         OscWinBuff[i][7] := #131;
  627.         FOR j := 5 TO 50 DO BEGIN
  628.           OscWinBuff[i][j*2]   := col[2];
  629.           OscWinBuff[i][j*2-1] := #0;
  630.         END;
  631.       END;
  632.       OscWinBuff[15][8] := col[1];
  633.       OscWinBuff[15][7] := #150;
  634.       FOR j := 5 TO 50 DO BEGIN
  635.         OscWinBuff[15][j*2]   := col[1];
  636.         OscWinBuff[15][j*2-1] := #148;
  637.       END;
  638.  
  639.       Ofs := ParseCoords(x+1, y+1);
  640.       FOR i := 1 TO 16 DO BEGIN
  641.         Move(OscWinBuff[i], Ptr(ScrSegment, Ofs)^, SIZEOF(OscWinBuff[1]));
  642.         INC(Ofs, ScreenBytesX);
  643.       END;
  644.     END;
  645.   END;
  646. *)
  647.  
  648.  
  649. PROCEDURE UpdateOscilloscInfo;
  650.   CONST
  651.     Count    : WORD = 0;
  652.     Semaphor : BYTE = 0;
  653.     i        : WORD = 0;
  654.     j        : WORD = 0;
  655.     ofs      : WORD = 0;
  656.   LABEL
  657.     Fin;
  658.   BEGIN
  659.     IF Semaphor > 0 THEN EXIT;
  660.  
  661.     INC(Semaphor);
  662.  
  663.     WITH wOscillosc DO BEGIN
  664.       IF NOT (act AND vis) THEN GOTO Fin;
  665. {
  666.       IF forz THEN BEGIN
  667.         InitOscilloscInfo;
  668.       END;
  669. }
  670.  
  671.       INC(Count);
  672.       IF Count < 1 THEN GOTO Fin;
  673.  
  674.       Count := 0;
  675.  
  676.       FillWithSamples(OscSamples, 46*4);
  677.  
  678.       ASM
  679.         CLD
  680.         MOV     CX,12
  681.         MOV     DI,OFFSET OscWinBuff + 51*2*2 + 8
  682.         PUSH    DS
  683.         POP     ES
  684.         MOV     DX,51*2 - 46*2
  685.         MOV     AH,BYTE PTR [wOscillosc.col[2]]
  686.         XOR     AL,AL
  687. @@lp1:   PUSH   CX
  688.          MOV    CX,46
  689.          REP STOSW
  690.          POP    CX
  691.          ADD    DI,DX
  692.          LOOP   @@lp1
  693.       END;
  694.  
  695.       ASM
  696.  
  697.         CLD
  698.         MOV     CH,46
  699.         MOV     SI,OFFSET OscSamples
  700.         MOV     BX,OFFSET OscWinBuff + 51*2*2 + 8
  701. @@lp1:   MOV    CL,4
  702. @@lp2:    LODSW
  703.           XOR   AH,$80
  704.  
  705.           XOR   DX,DX
  706.           MOV   DI,1821
  707.           DIV   DI
  708.  
  709.           MOV   DL,3
  710.           DIV   DL
  711.           MOV   DL,AH
  712.  
  713.           MOV   DI,CX
  714.           DEC   CL
  715.           ADD   CL,CL
  716.           INC   DL
  717.           SHL   DL,CL
  718.           MOV   CX,DI
  719.  
  720.           MOV   DH,51*2
  721.           MUL   DH
  722.           ADD   AX,BX
  723.           XCHG  BX,AX
  724.           ADD   [BX],DL
  725.           XCHG  BX,AX
  726.  
  727.           DEC   CL
  728.           JNZ   @@lp2
  729.          INC    BX
  730.          INC    BX
  731.          DEC    CH
  732.          JNZ    @@lp1
  733.  
  734.       END;
  735.  
  736.       Ofs := ParseCoords(x+5, y+3);
  737.       FOR i := 3 TO 14 DO BEGIN
  738.         Move(OscWinBuff[i][9], Ptr(ScrSegment, Ofs)^, 46*2);
  739.         INC(Ofs, ScreenBytesX);
  740.       END;
  741.  
  742.     END;
  743.  
  744. Fin:
  745.     wOscillosc.forz := FALSE;
  746.  
  747.     DEC(Semaphor);
  748.  
  749.   END;
  750.  
  751.  
  752.  
  753.  
  754. PROCEDURE InitPlayData(VAR Song: TSong);
  755.   CONST
  756.     i     : WORD           = 0;
  757.     j     : WORD           = 0;
  758.     Instr : PInstrumentRec = NIL;
  759.   BEGIN
  760.  
  761.     LastFilterOn  := fmNone;
  762.     LastFilterOff := fmNone;
  763.     LastFilter    := FALSE;
  764.  
  765.     FillChar(barlen, SizeOf(barlen), 0);
  766.     WITH wPlayBars DO BEGIN
  767.       FOR i := 1 TO 4 DO
  768.         barofs[i] := ParseCoords(wPlayBars.x + 1, wPlayBars.y + i);
  769.       forz := TRUE;
  770.       act  := TRUE;
  771.       vis  := TRUE;
  772.     END;
  773.  
  774.  
  775.     FOR i := 0 TO 64 DO
  776.       STR(i : 2, VolumeStrings[i]);
  777.  
  778.     FillChar(DispVolumes, SIZEOF(DispVolumes), $FF);
  779.     FillChar(DispNotes,   SIZEOF(DispNotes),   0);
  780.     FillChar(RealVolumes, SIZEOF(RealVolumes), $FF);
  781.     FillChar(RealNotes,   SIZEOF(RealNotes),   0);
  782.  
  783.     FillChar(DispSplName, SIZEOF(DispSplName), 0);
  784.  
  785.     FillChar(DispSamples, SIZEOF(DispSamples), sfNoSample);
  786.     FillChar(RealSamples, SIZEOF(RealSamples), sfNoSample);
  787.  
  788.     FOR i := 1 TO Song.Instruments.Count DO BEGIN
  789.       STR(i : 2, SampleStrings[i]);
  790.       SampleStrings[i] := SampleStrings[i] + ' ' + Song.GetInstrument(i)^.GetName;
  791.       Instr := Song.GetInstrument(i)^.Instr;
  792.       IF (Instr <> NIL) AND (Instr^.Len <> 0) THEN
  793.         BEGIN
  794.           DispSamples[i] := sfNotUsed;
  795.           RealSamples[i] := sfNotUsed;
  796.         END;
  797.     END;
  798.  
  799.     siTickForce    := FALSE;
  800.     siPermiso      := TRUE;
  801.     siCounter      := 0;
  802.  
  803.     FillChar(DispPermisos, SIZEOF(DispPermisos), 0);
  804.   END;
  805.  
  806.  
  807.  
  808.  
  809.  
  810. END.
  811.